<!DOCTYPE html>
<html lang="en">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Porting to GCC 4.9</title>
<link rel="stylesheet" type="text/css" href="https://gcc.gnu.org/gcc.css" />
</head>

<body>
<h1>Porting to GCC 4.9</h1>

<p>
The GCC 4.9 release series differs from previous GCC releases in
<a href="changes.html">a number of ways</a>. Some of
these are a result of bug fixing, and some old behaviors have been
intentionally changed in order to support new standards, or relaxed
in standards-conforming ways to facilitate compilation or run-time
performance.  Some of these changes are not visible to the naked eye
and will not cause problems when updating from older versions.
</p>

<p>
However, some of these changes are visible, and can cause grief to
users porting to GCC 4.9. This document is an effort to identify major
issues and provide clear solutions in a quick and easily searched
manner. Additions and suggestions for improvement are welcome.
</p>

<!--
<h2>General issues</h2>
-->

<!--
<h3>New warnings</h3>
-->

<h2>C/C++ language issues</h2>

<h3>Invalid OpenMP <code>#pragma omp end</code> directive now diagnosed</h3>

<p> GCC no longer accepts invalid OpenMP like: </p>

<pre><code>
  #pragma omp critical
    foo ();
  #pragma omp end critical
</code></pre>

<p>This example now gives the following diagnostic:</p>

<pre>
<b>t.c:6:19:</b> <span class="boldred">error:</span> expected &lsquo;<b>declare</b>&rsquo; before &lsquo;<b>critical</b>&rsquo;
   #pragma omp end critical
                   <span class="boldlime">^</span>
</pre>

<p>There is no <code>#pragma omp end critical</code> directive for C/C++
(whereas for Fortran there is <code>!$omp end critical</code>) but before
OpenMP 4.0 support was added, this would be diagnosed only with
<code>-Wunknown-pragmas</code>. As OpenMP 4.0 includes the
<code>#pragma omp end declare target</code> directive, this is now a parsing
error.</p>

<h3>Null pointer checks may be optimized away more aggressively</h3>

<p> GCC might now optimize away the null pointer check in code like:</p>

<pre><code>
  int copy (int* dest, int* src, size_t nbytes) {
    memmove (dest, src, nbytes);
    if (src != NULL)
      return *src;
    return 0;
  }
</code></pre>

<p>The pointers passed to <code>memmove</code> (and similar functions in
<code>&lt;string.h&gt;</code>) must be non-null even when
<code>nbytes==0</code>, so GCC can use that information to remove the check
after the <code>memmove</code> call. Calling <code>copy(p, NULL, 0)</code>
can therefore deference a null pointer and crash.</p>

<p>The example above needs to be fixed to avoid the invalid
<code>memmove</code> call, for example:</p>

<pre><code>
    if (nbytes != 0)
      memmove (dest, src, nbytes);
</code></pre>

<p>This optimization can also affect implicit null pointer checks such as
the one done by the C++ runtime for the <code>delete[]</code> operator.</p>


<h2>C language issues</h2>

<h3>Right operand of comma operator without effect</h3>

<p>GCC now warns about unused right-hand side of a comma expression that
contains no side effects:</p>

<pre><code>
  int i = 42; 
  bar (), i;
</code></pre>

<p>This example now gives the following diagnostic:</p>

<pre>
<b>w.c:5:9:</b> <span class="boldmagenta">warning:</span> right-hand operand of comma expression has no effect [-Wunused-value]
   bar (), i;
         <span class="boldlime">^</span>
</pre>

<p>To suppress this warning cast the right-hand operand to <code>void</code>:</p>

<pre><code>
  int i = 42; 
  bar (), (void) i;
</code></pre>


<h2>C++ language issues</h2>

<h3>Shadowing name of exception in <code>catch</code> handler now rejected</h3>

<p> GCC by default no longer accepts code such as: </p>

<pre><code>
  try {
    // ...
  } catch (const E&amp; e) {
    int e = 0;
  }
</code></pre>

<p>This example now gives the following diagnostic:</p>

<pre>
<b>e.cc:8:9:</b> <span class="boldred">error:</span> redeclaration of &lsquo;<b>int e</b>&rsquo; [-fpermissive]
     int e = 0;                                                                       
         <span class="boldlime">^</span>
<b>e.cc:7:21:</b> <span class="boldcyan">note:</span> &lsquo;<b>const E&amp; e</b>&rsquo; previously declared here
   } catch (const E&amp; e) {                                                             
                     <span class="boldlime">^</span>
</pre>

<p>
The standard says the example is ill-formed, so GCC was changed to reject it
for <a href="https://gcc.gnu.org/PR31952">PR31952</a>.

To fix the error either rename one of the variables or use an additional
nested scope for the second one.
</p>

<h3>Default arguments on redeclaration of member function of class template now rejected</h3>

<p> GCC by default no longer accepts code such as: </p>

<pre><code>
  template&lt;class T&gt;
  struct A
  {
    void f(int);
  };

  template&lt;class T&gt;
  void A&lt;T>::f(int i=0) { }
</code></pre>

<p>This example now gives the following diagnostic:</p>

<pre>
<b>r.cc:8:21:</b> <span class="boldred">error:</span> redeclaration of &lsquo;<b>void A&lt;T&gt;::f(int)</b>&rsquo; may not have default arguments [-fpermissive]
</pre>

<p>
The standard says the example is ill-formed, so GCC was changed to reject it
for <a href="https://gcc.gnu.org/PR54485">PR54485</a>.

To fix the error the default argument must appear when the member function
is first declared.
</p>

<h3>Header <code>&lt;memory&gt;</code> changes</h3>

<p>The contents of the <code>&lt;memory&gt;</code> header were reorganized to
allow easier reuse within libstdc++.
As a result, some code which directly includes headers such as
<code>&lt;bits/shared_ptr.h&gt;</code> will no longer compile and may produce
a diagnostic like:</p>
<pre>
<b>/usr/include/c++/4.9.0/bits/shared_ptr_base.h:</b> In member function &lsquo;<b>virtual void* std::_Sp_counted_deleter&lt;_Ptr, _Deleter, _Alloc, _Lp&gt;::_M_get_deleter(const std::type_info&amp;)</b>&rsquo;:
<b>/usr/include/c++/4.9.0/bits/shared_ptr_base.h:479:39:</b> <span class="boldred">error:</span> must #include &lt;typeinfo&gt; before using typeid
         return __ti == typeid(_Deleter) ? &amp;_M_impl._M_del() : nullptr;
                                       <span class="boldlime">^</span>
</pre>

<p>All <code>&lt;bits/xxx.h&gt;</code> headers are internal library headers
and including them directly is not supported and may be made into a hard
error in a future GCC release.</p>

<h3>Header <code>&lt;cstddef&gt;</code> changes</h3>

<p>The <code>&lt;cstddef&gt;</code> header was updated for C++11 support and
this breaks some libraries which misuse macros meant for internal use by GCC
only.
For instance with GMP versions up to 5.1.3, you may see: </p>
<pre>
<b>/usr/include/c++/4.9.0/cstddef:51:11:</b> <span class="boldred">error:</span> &lsquo;<b>::max_align_t</b>&rsquo; has not been declared
   using ::max_align_t;
           <span class="boldlime">^</span>
</pre>

<p>Another possible error is:</p>
<pre>
<b>someheader.h:99:13:</b> <span class="boldred">error:</span> &lsquo;<b>ptrdiff_t</b>&rsquo; does not name a type
</pre>
<p>A workaround until libraries get updated is to include
<code>&lt;cstddef&gt;</code> or <code>&lt;stddef.h&gt;</code> before any
headers from that library.</p>

<h3>Functions returning abstract class types</h3>

<p>GCC now checks return types more strictly and will reject declarations of
functions which return abstract types, including in uninstantiated templates
and in typedefs to function pointers. Returning an abstract type is not
possible so the code must be fixed.</p>


<!--
<h3>Java issues</h3>
-->

<h3>Links</h3>

<p>
Matthias Klose,
 <a href="https://gcc.gnu.org/ml/gcc/2014-01/msg00237.html">Debian test rebuild on x86_64-linux-gnu with trunk 20140118</a>
</p>

</body>
</html>
